﻿#region Using Directives

    using System;
    using System.Collections.Generic;

#endregion

namespace MarketPulse.BusinessLogic.Legacy
{
   
    #region Question Class

        /// <summary>
        /// Class used to represent a question item
        /// </summary>
        public class Question
        {

            #region Enumerations

                /// <summary>
                /// Enumeration used to hold the types available for this question
                /// </summary>
                public enum QuestionType
                {
                    Scored,
                    Unscored
                }

                /// <summary>
                /// Enumeration used to describe the different types of response available for a question
                /// </summary>
                public enum ResponseType
                {
                    SingleChoice,
                    MultipleChoice,
                    SelectAll,
                    FreeText
                }

            #endregion

            #region Constructors

                /// <summary>
                /// Default constructor for this class
                /// </summary>
                public Question()
                {
                    ID = 0;
                    Text = string.Empty;
                    DisplayNumber = 1;
                    DisplayOrder = 1;
                    PossibleScore = 0;
                    Type = QuestionType.Unscored;
                    QuestionResponseType = ResponseType.SingleChoice;
                    AnswerOptions = new AnswerOptionCollection();
                    //mScore = 0.0;
                }

                //TODO: Refactor this contructor to include all parameters

                /// <summary>
                /// Overloaded constructor for this class that accepts and sets a list of parameters
                /// </summary>
                /// <param name="id">The ID for this question</param>
                /// <param name="questionText">The text to display for this question</param>
                /// <param name="displayOrder">The order in which to display this question</param>
                /// <param name="questionNumber">The visible number for this question</param>
                /// <param name="responseType">The type of response expected for this question</param>
                public Question(int id, string questionText, int displayOrder, int questionNumber, int possibleScore, QuestionType questionType, ResponseType responseType)
                {
                    ID = id;
                    Text = questionText;
                    DisplayNumber = questionNumber;
                    DisplayOrder = displayOrder;
                    PossibleScore = possibleScore;
                    Type = questionType;
                    QuestionResponseType = responseType;
                    AnswerOptions = new AnswerOptionCollection();
                    //mScore = 0.0;
                }

            #endregion

            #region Properties

                /// <summary>The ID for this question</summary>
                public int ID { get; set; }

                /// <summary>The text to display for this question</summary>
                public string Text { get; set; }

                /// <summary>The instructions to display for this question</summary>
                public string Instructions { get; set; }

                /// <summary>The order in which to display this question</summary>
                public int DisplayOrder { get; set; }

                /// <summary>The visible number for this question</summary>
                public int DisplayNumber { get; set; }

                /// <summary>The maximum score possible score for this question</summary>
                public int PossibleScore { get; set; }

                /// <summary>The type of this question</summary>
                public QuestionType Type { get; set; }

                /// <summary>The type of response expected for this question</summary>
                public ResponseType QuestionResponseType { get; set; }

                /// <summary>The answer options available for this question</summary>
                public AnswerOptionCollection AnswerOptions { get; set; }

                /// <summary>Whether this question allows the user to select all responses</summary>
                public bool AllowSelectAll { get; set; }

                ///// <summary>The page this question should be displayed on</summary>
                //public int PageNumber { get; set; }

                /// <summary>The container this question should be displayed in</summary>
                public int ContainerID { get; set; }

                /// <summary>The combined score for the answer options selected for this question</summary>
                public double Score { get { return AnswerOptions.CombinedScore; } }

                /// <summary>Whether any options have been selected for this question</summary>
                public bool IsValid { get { return AnswerOptions.AnyAreResponses; } }

                /// <summary>Whether the score is visible or not</summary>
                public bool ScoreVisible { get; set; }

                public bool HasDependancy { get; set; }

                /// <summary>The path to the image to use to mark the status of this question</summary>
                public string StatusImagePath { get; set; }

            #endregion
        }

    #endregion

    #region QuestionCollection Class

                    /// <summary>
                    /// Class used to represent a collection of Question items
                    /// </summary>
                    public class QuestionCollection : List<Question>
                    {

                        #region Methods

                            /// <summary>
                            /// Method used to find a specific question based on the ID supplied
                            /// </summary>
                            /// <param name="id">The ID of the question to find</param>
                            /// <returns>A valid question object</returns>
                            public Question FindByID(int id)
                            {
                                Question temporaryQuestion = this.Find(delegate(Question question)
                                {
                                    return (question.ID == id);
                                });
                                return temporaryQuestion;
                            }

                            /// <summary>
                            /// Method used to find a specific set of questions based on the Page ID supplied
                            /// </summary>
                            /// <param name="id">The id of the container to find questions for</param>
                            /// <returns>A valid subset of questions </returns>
                            public List<Question> FindByContainerID(int id)
                            {
                                ////QuestionCollection returnValue = new QuestionCollection();

                                List<Question> returnValue = this.FindAll(delegate(Question question)
                                {
                                    return (question.ContainerID == id);
                                });

                                //var returnValue = this.FindAll(q => q.ContainerID == id);

                                return returnValue;
                            }

                            //TODO: Test out sscore by section 
                            /// <summary>
                            /// Method used to calculate the total score achieved for a given container (section or page)
                            /// </summary>
                            /// <param name="containerID">The id of the container to retreive the total score for</param>
                            /// <returns>A double value representing the total score for the container specified</returns>
                            public double TotalScoreByContainer(int containerID)
                            {
                                double totalScore = 0.0;

                                List<Question> sectionQuestions = FindByContainerID(containerID);

                                // Loop through the collection and calculate the total score
                                sectionQuestions.ForEach(delegate(Question question)
                                {
                                    totalScore += question.Score;
                                });

                                return totalScore;
                            }

                            /// <summary>
                            /// Method used to calculate the possible score available for a given container (section or page)
                            /// </summary>
                            /// <param name="containerID">The id of the container to retreive the possible score for</param>
                            /// <returns>A double value representing the possible score for the container specified</returns>
                            public double PossibleScoreByContainer(int containerID)
                            {
                                double possibleScore = 0.0;

                                List<Question> sectionQuestions = FindByContainerID(containerID);

                                // Loop through the collection and calculate the total score
                                sectionQuestions.ForEach(delegate(Question question)
                                {
                                    possibleScore += question.PossibleScore;
                                });

                                return possibleScore;
                            }

                        #endregion

                        #region Properties

                            /// <summary>The total score for all question where answer options have been selected</summary>
                            public double TotalScore
                            {
                                get
                                {
                                    double totalScore = 0.0;

                                    // Loop through the collection and calculate the total score
                                    this.ForEach(delegate(Question question)
                                    {
                                        totalScore += question.Score;
                                    });

                                    return totalScore;
                                }
                            }

                            /// <summary>The combined possible available score for all questions</summary>
                            public double PossibleScore
                            {
                                get
                                {
                                    double possibleScore = 0.0;

                                    // Loop through the collection and calculate the total score
                                    this.ForEach(delegate(Question question)
                                    {
                                        possibleScore += question.PossibleScore;
                                    });

                                    return possibleScore;
                                }
                            }

                            /// <summary>Whether the score is visible for the questions in this collection</summary>
                            public bool ShowScores
                            {
                                set
                                {
                                    // Loop through the collection and hide the scores
                                    this.ForEach(delegate(Question question)
                                    {
                                        question.ScoreVisible = value;
                                    });
                                }
                            }

                        #endregion
                    }

                #endregion
      
}